--- title: "04-CSS 布局" created: 2025-11-25 tags: - 项目筑基 --- # CSS 布局 > 复合选择器到浮动布局:后代/子代/并集/交集、背景、显示模式、三大特性、盒子模型(礼盒与泡沫)、清除浮动五法与 BFC,布局思想的正式登场。 ## 选择器进阶 除 id、class、标签、通配符之外 还有一些选择器供解决更复杂的问题 ### 复合选择器 #### 后代选择器(空格) 根据 HTML 标签的嵌套关系,选择父元素 后代中 满足条件的元素 语法:选择器1 选择器2 { css } 在选择器1所找到标签的后代(儿子、孙子、重孙子…)中 找到满足选择器2的标签,设置样式 注意点: 1. 后代包括:儿子、孙子、重孙子…… 2. 后代选择器中,选择器与选择器之间通过 空格 隔开 ![[web-image100.png]] 如果要选中 div 中的这个 p 标签 以之前的方法需要加上一个 class 或者 id ![[web-image101.png]] 但现在可以使用后代选择器 `div p{}` 的形式去完成 空格是关键(前面的父级也可以是类名 空格后的不一定是子代 还能往后推) #### 子代选择器(>) 根据 HTML 标签的嵌套关系,选择父元素 子代中 满足条件的元素 语法:选择器1 > 选择器2 { css } 在选择器1所找到标签的子代(儿子)中,找到满足选择器2的标签,设置样式 注意: - 子代只包括:儿子 - 子代选择器中,选择器与选择器之间通过 > 隔开 ![[web-image102.png]] 若用后代选择器 则两者都会变 如果希望只变上面那个 就可以用子代选择器 ![[web-image103.png]] 只需上级 不一定要最外层的那个作为父 但层次一深就容易乱 #### 并集选择器(,) 对于不同的标签 如果想设置一样的样式 可以用类把它们框起来 也可以用并集 作用:同时选择多组标签,设置相同的样式 语法:选择器1 , 选择器2 { css } 找到 选择器1 和 选择器2 选中的标签,设置样式 注意: - 并集选择器中的每组选择器之间通过 , 分隔 - 并集选择器中的每组选择器可以是基础选择器或者复合选择器 - 并集选择器中的每组选择器通常一行写一个,提高代码的可读性 ![[web-image104.png]] ![[web-image105.png]] #### 交集选择器(挨着) 选中页面中 同时满足 多个选择器的标签 语法:选择器1选择器2 { css } (既又原则) 找到页面中 既 能被选择器1选中,又 能被选择器2选中的标签,设置样式 注意: 1. 交集选择器中的选择器之间是紧挨着的,没有东西分隔 2. 交集选择器中如果有标签选择器,标签选择器必须写在最前面 ![[web-image106.png]] 点号(.)是 class 带的 p.box 两个标签是连着的 没带其他符号 #### hover 伪类选择器 选中鼠标悬停在元素上的状态,设置样式 语法:选择器:hover { css } 伪类选择器选中的元素的某种状态 不只是超链接 任何一个标签都可以写 hover 很多高级的功能都由此产生 从这里就开始慢慢过渡到布局思想了 以 div 为一个块 将元素分块放置、展示 在 div 中又会有很多类 有很多其他标签 嵌套一深 这些复合选择器、并集选择器就变得非常常用 ## Emmet 语法 通过简写语法,快速生成代码 ![[web-image109.png]] 直接 .类名 默认生成 div class 要指定生成某个标签带类 标签名.类名 回车 p.box (id 同理 . 换成 #) 生成两个同级标签: div+p 回车 得到 `
` 和 `

` 生成父子级标签: div>p 回车 得到 `

` 于是引出列表的写法: - ul>li 回车 - 生成三对 li 就 ul>li*3 - ul>li{111}*3 生成 3 个 111 的列表 - ul>li{$}*3 生成三行 分别为 1 2 3 在 css 中也有简写 比如: - font-size fsz 回车 - font-weight fw 回车 或者 fw700 回车 - background-color bgc 回车 (就是记单词首字母) 宽 300 高 200 背景粉 w300+h200+bgc 回车 而后改一下颜色即可 ## 背景 ### 背景颜色 属性名:background-color(bgc) 属性值:颜色取值——关键字、rgb 表示法、rgba 表示法、十六进制…… 背景颜色默认值是透明: rgba(0,0,0,0) 、transparent 背景颜色不会影响盒子大小,并且还能看清盒子的大小和位置,一般在布局中会习惯先给盒子设置背景颜色 ### 背景图片 可以与背景颜色同时设置 图片会在颜色上面 引入背景图片:background-image(bgi) ```css background-image: url(./images/1.jpg); ``` url 中可以省略引号 因为尺寸和盒子的大小可能不尽相同 所以背景图片在盒子中的展示可能不是刚好适应填满的 如果小了就会默认复制好几个相同的图片去把盒子填满 如果大了 则会只显示盒子大小的那部分图片 (背景图片仅仅是指给盒子起到装饰效果,类似背景颜色,不能撑开盒子) 主要是背景图片小于盒子的这种情况 涉及到两个方面:平铺和位置 如果不进行设置 那默认是在水平和垂直方向平铺的 设置背景平铺:background-repeat(bgr) ![[web-image110.png]] 如果不选择平铺 那就有个显示位置的问题 通常是居中 以盒子的左上角为原点 向下为 y+ 向右为 x+ 设置背景图片位置:background-position(bgp) (跟数字也行 左上负 右下正) ![[web-image111.png]] ![[web-image112.png]] ### 背景连写与 size 和 font 文字样式一样 背景也可以进行一个连写 background(bg) 不同的是它不分先后顺序 但通常有一套逻辑 推荐:background:color image repeat position 如果盒子大小和背景图片大小一样,可以直接写 background:url() ![[web-image113.png]] 等同于 ![[web-image114.png]] ![[web-image115.png]] ```css background-size: 宽 高; ``` 可以跟 px、%、contain(包含 等比例缩放 直到不会超过盒子)、cover(覆盖 等比例缩放 直到填满整个盒子) ``` background: color image repeat position/size; ``` ## img 与 background-image 需要在网页中展示一张图片的效果? 方法一:直接写上 img 标签即可 img 标签是一个标签,不设置宽高默认会以原尺寸显示 方法二:div 标签 + 背景图片 需要设置 div 的宽高,因为背景图片只是装饰的 CSS 样式,不能撑开 div 标签 ## 元素显示模式 ### 块级元素 - 独占一行(一行只能显示一个) - 宽度默认是父元素的宽度(特殊减去 padding),高度默认由内容撑开 - 可以设置宽高 比如:div、p、h 系列、ul、li、dl、dt、dd、form、header、nav、footer…… ![[web-image116.png]] ### 行内元素 - 一行可以显示多个 - 宽度和高度默认由内容撑开 - 不可以设置宽高 比如:a、span、b、u、i、s、strong、ins、em、del…… ![[web-image117.png]] ### 行内块元素 - 一行可以显示多个 - 可以设置宽高 比如:input、textarea、button、select…… img 标签也有行内块元素的特点 (两张连续的图片在一行显示 可以设置图片尺寸——满足行内、块的优点) ### 元素显示模式转换 改变元素默认的显示特点,让元素符合布局要求 ![[web-image118.png]] 常用的是把 div 转为行内块 ![[web-image119.png]] ![[web-image120.png]] 以及把 span 标签转为块级标签 ### 嵌套 以现在块的思想去分析嵌套 很明显 大的嵌套小的 块级元素一般作为大容器,可以嵌套:文本、块级元素、行内元素、行内块元素…… 但是:**p 标签中不要嵌套 div、p、h 等块级元素** a 标签内部可以嵌套任意元素 但是:**a 标签不能嵌套 a 标签** ### 居中拓展 ![[web-image121.png]] ## CSS 特性 ### 继承性 子元素继承父元素的特点 像一系列文字控制属性都可以继承 color、font-style、font-weight、font-size、font-family、text-indent、text-align、line-height…… ![[web-image122.png]] 未给 span 设置 red 但它在 div 中 所以继承了 div 的 red 但不是文字方面的就不能继承 比如宽高 给 div 设置宽高是给 div 的盒子设置 span 的宽高与文字有关 不继承 利用继承性就可以给一大片东西同时加属性 节省代码 如果有个例特殊就拎出来单独设置 对于超链接 a 标签 不会因为设置 div 为 red 而变红 a 本身就具有蓝色的一个属性 自己有就用自己的不用继承的(重写) 同理 标题不会受 div 字号的继承 ### 层叠性 给同一个标签设置不同的样式 → 此时样式会层叠叠加 → 会共同作用在标签上 给同一个标签设置相同的样式 → 此时样式会层叠覆盖 → 最终写在最后的样式会生效 当样式冲突时,只有当选择器优先级相同时,才能通过层叠性判断结果 ### 优先级 不同选择器具有不同的优先级 优先级高的选择器样式会覆盖优先级低选择器样式 优先级公式: ``` 继承 < 通配符选择器 < 标签选择器 < 类选择器 < id选择器 < 行内样式 < !important ``` 注意: 1. !important 写在属性值的后面,分号的前面! 2. !important 不能提升继承的优先级,只要是继承优先级最低! 3. 实际开发中不建议使用 !important 。 权重叠加计算 如果是复合选择器,需要通过权重叠加计算方法 判断最终哪个选择器优先级最高会生效 计算公式:(每一级之间不存在进位) ![[web-image123.png]] 比较规则: - 先比较第一级数字,如果比较出来了,之后的统统不看 - 如果第一级数字相同,此时再去比较第二级数字,如果比较出来了,之后的不看 - 如果最终所有数字都相同,表示优先级相同,则比较层叠性(谁写在下面,谁说了算) 注意:!important 如果不是继承,则权重最高 ## 盒子模型 浏览器在渲染(显示)网页时,会将网页中的元素看做是一个个的矩形区域,我们也形象的称之为——盒子 页面中的每一个标签,都可看做是一个 "盒子",以盒子视角更方便的进行布局 每个盒子分别由:内容区域(content)、内边距区域(padding)、边框区域(border)、外边距区域(margin)构成 ![[web-image124.png]] ![[web-image125.png]] ### border 直接对一个块级元素 div 进行 width、height 设置 就是给盒子模型的内容区域设置大小 对于这样的一块区域 可以给它加上边框——border ![[web-image126.png]] 当然可以连写——border:10px solid red; (快捷键 bd+tab) 在设计上 如果加上 4 个边框会比较丑 所以往往会只加下边框线 实现类似于 hr 的效果 so—— 单方面设置边框——border-方位 - border-left: - border-right: - border-top: - border-bottom: ### padding(礼盒里的泡沫) 设置边框和内容之间的距离 (礼盒里的泡沫) 有四个方向 那么就有很多种赋值方式: - 写 4 个值 那就是上 右 下 左 顺时针依次赋值 - 写 3 个值 那就是上 右 下 顺时针赋 3 个值 左会默认与右相等 - 写 2 个值 那就是给上和右赋值 下和上默认相等 左和右默认相等 - 写 1 个值 就默认上下左右都是相同的内边距 不希望这样顺时针赋值 想要指定给某个方向赋值也是可以的 同样是加上方位:padding-left/right/top/bottom 需要注意的是 **border 和 padding 都是会撑大盒子的** 比如说如果一开始设置了 w300px h400px 再加上 10px 的 border 20px 的 padding 这样一来盒子就会变成 w360px、h460px 如果想保持总体大小不变 有两种方法: 一是自己手动把之前设置的宽高减小 二呢就是加上一个属性 ```css box-sizing : border-box ; ``` 以实现自动内减 这个可以在某个 div 标签里加 也可以直接在 * 里面加 ```css * { box-sizing : border-box ; } ``` ### margin 还有一个外边距 margin 之前居中的时候有用过 ``` margin 0 auto; ``` 用刚才的 padding 的方式理解 该盒子与页面(或者其他盒子)的上边距为 0 左右边距为自适应 ![[web-image127.png]] 单方向设置还是同理 加上方位 margin 就是两个礼盒之间的一个距离 在很多标签中会默认有一个 margin 但设计时往往不希望这个默认的边距 会影响设计师的一个设计 所以 可以利用通配符选择器 去把这些默认的 margin 消除掉 方便自己后续设计 那么 * 里就可以再加俩东西 ```css * { margin: 0; padding: 0; box-sizing : border-box ; } ``` 还有一种写法 ![[web-image128.png]] 利弊呢看情况吧 在两个盒子之间真正的距离其实是两个相邻 margin 之和 这个应该很容易理解 ### 外边距折叠现象 **一、合并现象** 垂直布局的块级元素,上下的 margin 会合并 导致最终两者距离为 margin 的最大值 解决:只给其中一个盒子设置 margin **二、塌陷现象** 互相嵌套的块级元素,子元素的 margin-top 会作用在父元素上 导致父元素一起往下移动 解决: 1. 给父元素设置 border-top 或者 padding-top(分隔父子元素的 margin-top) 2. 给父元素设置 overflow:hidden 3. 转换成行内块元素 4. 设置浮动 ### 行内元素的 margin 和 padding 无效情况 给行内元素设置 margin 和 padding 时 会导致: 水平方向的 margin 和 padding 布局中有效 而垂直方向的 margin 和 padding 布局中无效 ## 浮动 先铺垫一下 了解一个东西 ### 结构伪类选择器(铺垫) 根据元素在 HTML 中的结构关系查找元素 以列表为例 ![[web-image129.png]] ```css ``` 结构伪类选择器里是可以填公式的 比如说实际情况中 表格的奇偶行样式可能不同 如果一个一个选中就过于麻烦 ![[web-image130.png]] ```css /* 偶数 */ li:nth-child(2n) { /* 奇数 */ li:nth-child(2n+1) { /* 找到前3个 */ li:nth-child(-n+3) { /* 4的倍数 */ li:nth-child(4n) { ``` ### 伪元素(铺垫) ```html
``` ![[web-image131.png]] ![[web-image132.png]] ![[web-image133.png]] https://v.douyin.com/SsLg4Hd/ ### 标准流 又称文档流,是浏览器在渲染显示网页内容时默认采用的一套排版规则,规定了应该以何种方式排列元素 如: - 块级元素:从上往下,垂直布局,独占一行 - 行内元素 或 行内块元素:从左往右,水平布局,空间不够自动折行 布局网页不可能只用标准流 想要预期效果就必须加上浮动、定位等元素 ### 为什么要浮动 想让 div 在一行排 用之前的方式是 转成行内块 但是 两个 display:inline-block 变化来的块级元素 如果两个标签间有回车 会默认当做空格处理 ![[web-image134.png]] 若要消除该空隙 就需要把 div 写在同一行 ![[web-image135.png]] 可想而知 代码一长 可读性将变得非常糟糕 所以 排版就采取了另一种方式——浮动 ### 图文环绕 早期发明浮动就是为了实现图文环绕效果 而后来越来越被用于排版布局 在同一个块级元素中要实现图文环绕 只需给 img 标签加上 float 属性即可 ![[web-image136.png]] ### 网页布局 浮动元素会脱离标准流(简称:脱标),在标准流中不占位置 相当于从地面飘到了空中 浮动元素要比标准流高半个级别,可以覆盖标准流中的元素 浮动找浮动,下一个浮动元素会在上一个浮动元素后面左右浮动 (相当于图层 浮动元素在同一层 非浮动元素在同一层) 浮动元素有特殊的显示效果: - 一行可以显示多个 - 可以设置宽高 但是——浮动的元素不能通过 text-align:center 或者 margin:0 auto 来设置居中 (框里的文字可以居中在浮动元素上) ### 渲染效率 网页渲染也有先后顺序 所以写代码的先后顺序也和 sql 查询语句一样 事关效率问题 CSS 书写顺序: 1. 浮动/display 2. 盒子模型:margin、border、padding、宽、高、背景色 3. 文字样式 ### 案例 ![[web-image137.png]] 要实现这种布局 一般使用列表进行排版 ![[web-image138.png]] 但是这种列表是有符号的 想要消除符号 可以使用 ![[web-image139.png]] 对于每一个 li 元素 设置一下边距、宽高 当然 一开始想要消除默认边距 ![[web-image140.png]] 但是 在最右边的元素是没有右边距的 所以使用结构伪类 ![[web-image141.png]] 如果父级元素的宽度不够容纳所有子元素 就会默认换行 所以需要计算好这个值 ### 清除浮动 有时浮动会带来一些负面影响 比如子元素浮动就会脱标从而不占位置使得下方元素自动上移扰乱布局 要消除这种浮动带来的负面影响 就需要使父元素有一定高度 解决方法有 5 种: **(1)直接给父元素加上高度** 简单粗暴 但是有些布局中 这个父元素的高度是不能固定的 **(2)在父元素内容的最后再加上一个块级元素 设置 clear:both 属性** ```html
``` 但是这样每次都要多加一个块标签 让 html 结构变得很复杂 **(3)单伪元素消除** 原理:用伪元素去代替方法二中的额外标签 ![[web-image142.png]] ![[web-image143.png]] 直接给标签加类就能消除浮动 **(4)双伪元素消除** ![[web-image144.png]] **(5)直接给父元素加 overflow:hidden 即可** 选择器中选中父元素的标签 给出一行 overflow:hidden ### BFC 块格式化上下文(Block Formatting Context):BFC 是 Web 页面的可视 CSS 渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。 ➢ 创建 BFC 方法: 1. html 标签是 BFC 盒子 2. 浮动元素是 BFC 盒子 3. 行内块元素是 BFC 盒子 4. overflow 属性取值不为 visible。如:auto、hidden… 5. …… ➢ BFC 盒子常见特点: 1. BFC 盒子会默认包裹住内部子元素(标准流、浮动)→ 应用:清除浮动 2. BFC 盒子本身与子元素之间不存在 margin 的塌陷现象 → 应用:解决 margin 的塌陷 3. …… 根据学成项目 浮动相关排版已经了解 关于布局 除了标准流、浮动 还有一个定位(见下一篇) ## 附件 - [[web前端.docx|web前端.docx]] --- ⬅️ [[03-CSS 基础|03-CSS 基础]] 🏠 [[00-前端与可视化|00-前端与可视化]] ➡️ [[05-定位与装饰|05-定位与装饰]]